/**
 * @author		Sergey Suzdalskiy
 * @e-mail:		sergey.suzdalskiy@gmail.com
 */
package ua.kiev.gcore.net {
	import flash.events.EventDispatcher;
	import flash.system.Security;
	import flash.system.SecurityDomain;
	import flash.utils.Dictionary;
	
	import ua.kiev.gcore.net.command.Command;
	import ua.kiev.gcore.net.command.IProtocolParser;
	import ua.kiev.gcore.net.connections.Connection;
	import ua.kiev.gcore.net.connections.ConnectionAttributes;
	import ua.kiev.gcore.net.connections.HTTPConnection;
	import ua.kiev.gcore.net.connections.ServerMockConnection;
	import ua.kiev.gcore.net.connections.SocketConnection;
	import ua.kiev.gcore.net.connections.event.CommunicateEvent;
	
	public class ServerProxy extends EventDispatcher {
		
		/**
		 * Singleton
		 */
		private static var _instance:ServerProxy;
		
		public static function get instance():ServerProxy {
			
			if (_instance == null) {
				_instance = new ServerProxy();
			}
			
			return _instance;
		}
			

		
		private var connections:Dictionary = new Dictionary();
		private var id:uint = 0;
		/**
		 * create new connection
		 */
		public function addConnection(server:String, port:int, dataType:int, parser:IProtocolParser, connectionType:int = Connection.HTTP):Connection {			
			++id;
			var connectionAttributes:ConnectionAttributes = new ConnectionAttributes(server, port, dataType);
			var connection:Connection;
			switch(connectionType){
				case Connection.HTTP:
					connection = new HTTPConnection(id, connectionAttributes, parser);	
					break;
				case Connection.SOCET:
					connection = new SocketConnection(id, connectionAttributes, parser);
					break;
				case Connection.MOCK:
					connection = new ServerMockConnection(id, connectionAttributes, parser);
					break;
				default:
					connection = new HTTPConnection(id, connectionAttributes, parser);
					break;
			}
			
			if(connection){		
				connections[id] = connection;
				
				connection.addEventListener(CommunicateEvent.CONNECT, connectSuccesfulHandler);
				connection.addEventListener(CommunicateEvent.CONNECT_FAILED, connectFailedHandler);
				connection.init();
				
				return connection;
			}else{
				var newEvent:CommunicateEvent = new CommunicateEvent(CommunicateEvent.CONNECT_FAILED);
				newEvent.message = "create connection faile";
				dispatchEvent(newEvent);
				return null;
			}
		}
		
		/**
		 * destroy connection
		 */
		public function destroyConnection(id:int):void {
			if(connections[id]){
				(connections[id] as Connection).removeEventListener(CommunicateEvent.CONNECT, connectSuccesfulHandler);
				(connections[id] as Connection).removeEventListener(CommunicateEvent.CONNECT_FAILED, connectFailedHandler);
//				(connections[id] as Connection).removeEventListener(CommunicateEvent.DATA_RECEIVED, dataReceivedHandler);	
				(connections[id] as Connection).destroy();
				connections[id] = null;
				delete connections[id];
			}
		}
		
		
		public function dataReceivedHandler(command:*, id:int):void {
			if ((connections[id]) && (connections[id] as Connection).listener) {
				(connections[id] as Connection).listener.parse(command);
			} else {
				var event:CommunicateEvent = new CommunicateEvent(CommunicateEvent.DATA_RECEIVED);
				event.command = command;
				event.connectionId = id;
				event.message = "invalid connection id:" + id.toString();
				dispatchEvent(event);
			}
		}
		
		private function connectSuccesfulHandler(event:CommunicateEvent):void {
			dispatchEvent(event.clone());
		}
		
		private function connectFailedHandler(event:CommunicateEvent):void {
			dispatchEvent(event.clone());			
		}
	}
}

